
#ifdef INT
#  define TYP INTEGER
#else
#ifdef FLOAT
#  define TYP REAL
#else
 #error "Need to give MACRO definition for element type : -DTYPE_INT or -DTYPE_FLOAT"
#endif
#endif


PROGRAM PROG_PRINC
!
!compilation : gfortran prog_princ.f90 -fbounds-check
!
IMPLICIT NONE



!DECLARATION DES PARAMETRES


	! LA TAILLE DES MATRICES EST ENTREE EN LIGNE DE COMMANDE LORS DE L' EXECUTION

	INTEGER :: DIM1
	INTEGER :: F_COMPTEUR
	INTEGER :: I,J,P
	TYP :: S !POUR LA GENERATION DE NOMBRE ALEATOIRE
	

	REAL :: INTERMEDIAIRE
	INTEGER :: VALEURMAX,VALEURMIN

	INTEGER :: order
	CHARACTER(len=32) :: arg
	
	
 	!********************POUR LE STOCKAGE CSR
	INTEGER,DIMENSION(:),ALLOCATABLE :: IA
 	INTEGER,DIMENSION(:),ALLOCATABLE :: JA
 	TYP, DIMENSION (:), ALLOCATABLE :: VALUES

 	TYP,DIMENSION(:),ALLOCATABLE :: U
 	INTEGER :: IERR

	TYP,DIMENSION(:),ALLOCATABLE :: V

 
	!**lecture des arguments en ligne de commande
	DO P=0,2
		CALL get_command_argument(p, arg)
		IF (LEN_TRIM(arg) == 0) exit 
		!WRITE (*,*) TRIM(arg)
		IF (p == 1) THEN
			read ( arg , '(i10)') DIM1
		ELSEIF (p == 2) THEN
			read ( arg , '(i10)') F_COMPTEUR
		ENDIF
	END DO




	!********************POUR LE STOCKAGE CSR
	ALLOCATE (IA(DIM1+1))
	ALLOCATE (JA(DIM1))
    	ALLOCATE(VALUES(DIM1))
	ALLOCATE (U(DIM1))

	ALLOCATE (V(DIM1))

	VALEURMAX=100000
	VALEURMIN=-100000
	! PRENONS A DIAGONALE (COEFF ALEATOIRES)
	IA(DIM1+1)=1	
	DO I=1,DIM1
		IA(I)=1
		JA(I)=I 
		CALL RANDOM_NUMBER(INTERMEDIAIRE)
		VALUES(I)=INTERMEDIAIRE*(VALEURMAX-VALEURMIN)+VALEURMIN
		U(I)=I
	END DO  

  !AFFICHONS LA MATRICE IA        
!	 DO I=1,DIM1
!	   WRITE(*,*) IA(I), JA(I)
!	 END DO

	CALL SPMV_CSR(IA,JA,VALUES,U,V,DIM1,F_COMPTEUR)

	! ON DESALLOUE TOUT CE QU'ON A ALLOUE
	DEALLOCATE(U)
	DEALLOCATE(V)
	DEALLOCATE(IA)
	DEALLOCATE(JA)
    	DEALLOCATE(VALUES)

	!END DO

	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------ESPACE SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	CONTAINS

	!SUBROUTINES MATRICE CREUSE CSR
	!-----------------------------------------------------------------------------
	! Fonction : SPMV_CSR
	! Description :- calcul le produit matrice_creuse/vecteur et enregistre le temps d'execution et les parametre de la matrice dans un fichier
	!                pour un stockage creux du type Compressed Storage Row, on a un tableau de taille dim+1 qui stocke le nombre d'elements non nuls par ligne
	!                un tableau de taille le nombre de zero qui stocke les numéros des colonne des elements non nuls
	!                et un tableau de taille le nombre de zero qui stocke la valeurs des coefficients non nuls
	! Paramètres : - int *IA, stocke le nombre d'elements non nuls par ligne
	!              - itn *JA stocke les numéros de colonnes des elements non nuls
	!              - T *Values, le tableau de valeurs non nuls
	!              - T *u, le vecteur multiplie
	!              - T *v, le vecteur resultat
	! 			  - int dim la dimension de la matrice
	! Retour: aucun
	!-----------------------------------------------------------------------------
	SUBROUTINE SPMV_CSR(IA,JA,VALUES,U,V,DIM1,F_COMPTEUR)
	!DECLARATIONS PARAMETRES
	REAL *8:: T1,T2,TEMPS_MOY=0.0
	INTEGER :: I,K,COMPTEUR=0
	CHARACTER*80 :: FORME="stockage Compressed Storage Row"
	INTEGER, INTENT (IN) :: DIM1,F_COMPTEUR
	TYP,DIMENSION(:), INTENT (IN) :: VALUES
	TYP,DIMENSION(:), INTENT (IN) :: U
	INTEGER,DIMENSION (:), INTENT (IN) :: IA
	INTEGER,DIMENSION (:), INTENT (IN) :: JA
	TYP,DIMENSION(:), INTENT (OUT):: V

	!CALCUL PRODUIT
	DO COMPTEUR=1,F_COMPTEUR

		!TOP CHRONO
		CALL CPU_TIME(T1)
		DO I=1,DIM1
			DO K=IA(I),IA(I+1)
				V(I)=V(I)+VALUES(K)*U(JA(K))
		       !WRITE (6,*) V(I)
			END DO
		END DO
		!STOP CHRONO 
		CALL CPU_TIME(T2)

		TEMPS_MOY=T2-T1+TEMPS_MOY
	END DO
	TEMPS_MOY=TEMPS_MOY/F_COMPTEUR
	WRITE(*,*) TEMPS_MOY

	END SUBROUTINE SPMV_CSR

	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------END SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------

END PROGRAM PROG_PRINC

!------------------------------------------------------------------------------
!MESSAGE D'ERREUR RETOURNER DANS LE TERMINAL
!a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
!Abandon
!--------------------------------------------------------------------------------------
